package rt2

import (
	"fmt"
	"sync"
	"time"

	"gitee.com/copperxcx/utils"
)

const (
	// 回复任务最长持续1天时间
	ResValResponseTimeout = time.Hour * 24
)

type ResReqMissionData struct {
	names           []string
	intv            int32
	totalReplyTimes int32
	replyTimes      int32
	groupId         int32

	// 回复的帧序号
	seq int32

	// 执行回复的任务
	task utils.ITask
}

type ResReqMissionManager struct {
	mu sync.Mutex

	id      int32
	dataMap map[int32]*ResReqMissionData

	missionChan chan *ResReqMissionData

	running bool
}

func NewResReqMissionManager() *ResReqMissionManager {
	return &ResReqMissionManager{
		dataMap:     make(map[int32]*ResReqMissionData),
		missionChan: make(chan *ResReqMissionData, 10),
	}
}

func (r *ResReqMissionManager) Add(d *ResReqMissionData) {
	r.mu.Lock()
	defer r.mu.Unlock()

	r.id++
	r.dataMap[r.id] = d
	d.groupId = r.id
	fmt.Printf("mission progress: %d/%d  %d", d.replyTimes, d.totalReplyTimes, d.intv)

	// 组织回复任务：动作函数无操作，检测函数中发出回复任务
	d.task = utils.NewAsyncTask(fmt.Sprintf("res_req_mission_%d", r.id), ResValResponseTimeout*60*60, func() error { return nil }, func() error {
		d.replyTimes++
		// 触发回复任务
		r.missionChan <- d

		// 检测是否完成
		if d.totalReplyTimes != -1 && d.replyTimes >= d.totalReplyTimes {
			return nil
		}
		return fmt.Errorf("mission progress: %d/%d", d.replyTimes, d.totalReplyTimes)
	}, time.Duration(d.intv*1000), true)
	d.task.Run()
	fmt.Printf("mission status: %d", d.task.Status())
}

func (r *ResReqMissionManager) Remove(groupId int32) (*ResReqMissionData, error) {
	if d, ok := r.dataMap[groupId]; ok {
		d.task.Stop()
		delete(r.dataMap, groupId)
		return d, nil
	}
	return nil, fmt.Errorf("group %d not found", groupId)
}

func (r *ResReqMissionManager) Start() <-chan *ResReqMissionData {
	r.mu.Lock()
	defer r.mu.Unlock()
	if r.running {
		return r.missionChan
	}
	r.missionChan = make(chan *ResReqMissionData, 10)
	r.running = true
	return r.missionChan
}

func (r *ResReqMissionManager) Stop() {
	r.mu.Lock()
	defer r.mu.Unlock()
	if r.running {
		close(r.missionChan)
		r.running = false
	}
}
